package com.miaoshaoproject.service.impl;

import com.miaoshaoproject.dao.PromoDOMapper;
import com.miaoshaoproject.dataobject.PromoDO;
import com.miaoshaoproject.error.BussinessException;
import com.miaoshaoproject.error.EmBussinessError;
import com.miaoshaoproject.service.ItemService;
import com.miaoshaoproject.service.UserService;
import com.miaoshaoproject.service.model.ItemModel;
import com.miaoshaoproject.service.model.PromoModel;
import com.miaoshaoproject.service.PromoService;
import com.miaoshaoproject.service.model.UserModel;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class PromoServiceImpl implements PromoService {
    @Autowired
    private PromoDOMapper promoDOMapper;
    @Autowired
    private ItemService itemService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;

    @Override
    public PromoModel getPromoByItemId(Integer itemId) {

        //获取对应商品的秒杀活动信息
        PromoDO promoDO= promoDOMapper.selectByItemId(itemId);
        if (promoDO==null){
            return null;
        }
        //dataobject-->model
        PromoModel promoModel=convertFromDataObject(promoDO);

        //判断当前时间是否秒杀活动即将开始或正在进行
        if(promoModel.getStartDate().isAfterNow()){
            promoModel.setStatus(1);
        }else if(promoModel.getEndDate().isBeforeNow()){
            promoModel.setStatus(3);
        }else{
            promoModel.setStatus(2);
        }
        return promoModel;
    }


    private PromoModel convertFromDataObject(PromoDO promoDO){
        if (promoDO==null){
            return  null;
        }
        PromoModel promoModel=new PromoModel();
        BeanUtils.copyProperties(promoDO,promoModel);
        promoModel.setPromoItemPrice(new BigDecimal(promoDO.getPromoItemPrice()));
        promoModel.setStartDate(new DateTime(promoDO.getStartDate()));
        promoModel.setEndDate(new DateTime(promoDO.getEndDate()));
        return promoModel;
    }

    @Override
    public void publishPromo(Integer promoId) {
        //通过活动id获取活动
        PromoDO promoDO=promoDOMapper.selectByPrimaryKey(promoId);
        if(promoDO.getItemId()==null || promoDO.getItemId().intValue()==0){
             return;
        }

        ItemModel itemModel=itemService.getItemById(promoDO.getItemId());

        //将库存同步到redis内
        redisTemplate.opsForValue().set("promo_item_stock_"+itemModel.getId(),itemModel.getStock());

        //将秒杀大闸的限制数据设到redis内
        redisTemplate.opsForValue().set("promo_door_count_"+promoId,itemModel.getStock().intValue()*5);
    }

    @Override
    public String generateSecondKillToken(Integer promoId,Integer itemId,Integer userId) {
        //获取秒杀活动信息
        PromoDO promoDO= promoDOMapper.selectByPrimaryKey(promoId);
        //dataobject-->model
        PromoModel promoModel=convertFromDataObject(promoDO);
        if (promoModel==null){
            return null;
        }
        //判断当前时间是否秒杀活动即将开始或正在进行
        if(promoModel.getStartDate().isAfterNow()){
            promoModel.setStatus(1);
        }else if(promoModel.getEndDate().isBeforeNow()){
            promoModel.setStatus(3);
        }else{
            promoModel.setStatus(2);
        }
        if (promoModel.getStatus().intValue()!=2){
            return null;
        }

        //判断item信息是否存在
        ItemModel itemModel=itemService.getItemByIdInCache(itemId);
        if(itemModel==null){
            return null;
        }

        //判断用户是否存在
        UserModel userModel=userService.getUserModelByIdInCache(userId);
        if(userModel==null){
            return null;
        }

        // 获取秒杀大闸的count数量
        long result=redisTemplate.opsForValue().increment("promo_door_count_"+promoId,-1);
        if(result<0){
            return null;
        }

        //生成token并放入redis内
        String token= UUID.randomUUID().toString().replace("-","");
        redisTemplate.opsForValue().set("promo_token_"+promoId+"_userId_"+userId+"_itemId_"+itemId,token);
        redisTemplate.expire("promo_token_"+promoId+"_userId_"+userId+"_itemId_"+itemId,5,TimeUnit.MINUTES);
        return token;
    }
}
